home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
- #include <time.h>
- #include <stdarg.h>
- #include <conio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "iface.h"
- #include "trace.h"
- #include "pktdrvr.h"
- #include "commands.h"
- #include "session.h"
- #include "files.h"
-
- static void near ascii_dump __ARGS((FILE *fp,struct mbuf **bpp));
- static void near hex_dump __ARGS((FILE *fp,struct mbuf **bpp));
-
- /* Redefined here so that programs calling dump in the library won't pull
- * in the rest of the package
- */
- static char nospace[] = "No space!\n";
-
- void
- dump(struct iface *iface,int direction,unsigned type,struct mbuf *bp)
- {
- struct mbuf *tbp;
- void (*func) __ARGS((FILE *,struct mbuf **,int));
- int16 size;
- char *cp;
-
- if(iface == NULLIF)
- return;
-
- switch(direction) {
- case IF_TRACE_IN:
- iface->lastrecv = secclock();
- iface->rawrecvcnt++;
- break;
- case IF_TRACE_OUT:
- iface->lastsent = secclock();
- iface->rawsndcnt++;
- break;
- }
-
- if((Current != Trace && iface->trfile == NULLCHAR)
- || (iface->trace & direction) == 0)
- return; /* Nothing to trace */
-
- if(direction == IF_TRACE_IN && (iface->trace & IF_TRACE_NOBC)
- && (Tracef[type].addrtest != NULLFP) && (*Tracef[type].addrtest)(iface,bp) == 0)
- return; /* broadcasts are suppressed */
-
- cp = ctime(&currtime);
- cp[24] = '\0';
-
- trprintf(iface->trfp,"%s %s (%s):\n",
- iface->name,(direction & IF_TRACE_OUT) ? "sent" : "recv",cp);
-
- if(bp == NULLBUF || (size = len_p(bp)) == 0) {
- trprintf(iface->trfp,"empty packet\n");
- return;
- }
- dup_p(&tbp,bp,0,size);
-
- if(tbp != NULLBUF) {
- if((func = (type < NCLASS) ? Tracef[type].tracef : NULLVFP) != NULLVFP) {
- #ifdef MSDOS
- textattr(WHITE);
- #endif
- (*func)(iface->trfp,&tbp,1);
- #ifdef MSDOS
- textattr(LIGHTGRAY);
- #endif
- if(iface->trace & IF_TRACE_ASCII)
- /* Dump only data portion of packet in ascii */
- ascii_dump(iface->trfp,&tbp);
- else if(iface->trace & IF_TRACE_HEX) {
- free_p(tbp);
- dup_p(&tbp,bp,0,len_p(bp));
- /* Dump entire packet in hex/ascii */
- hex_dump(iface->trfp,&tbp);
- }
- } else {
- trprintf(iface->trfp,"%s",nospace);
- }
- }
- free_p(tbp);
- }
-
- /* Convert byte to two ascii-hex characters */
- static void near
- ctohex(char *buf,int16 c)
- {
- static char hex[] = "0123456789abcdef";
-
- *buf++ = hex[hinibble(c)];
- *buf = hex[lonibble(c)];
- }
-
- /* Print a buffer up to 16 bytes long in formatted hex with ascii
- * translation, e.g.,
- * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
- */
- static void near
- fmtline(FILE *fp,int16 addr,char *buf,int16 len)
- {
- char line[80];
- char *aptr, *cptr, c;
-
- memset(line,' ',sizeof(line));
- ctohex(line,(int16)hibyte(addr));
- ctohex(line+2,(int16)lobyte(addr));
- aptr = &line[6];
- cptr = &line[55];
- while(len-- != 0){
- c = *buf++;
- ctohex(aptr,(int16)uchar(c));
- aptr += 3;
- c &= 0x7f;
- *cptr++ = isprint(uchar(c)) ? c : '.';
- }
- *cptr++ = '\n';
- *cptr++ = '\0';
- trprintf(fp,"%s",line);
- }
-
- /* Dump an mbuf in hex */
- static void near
- hex_dump(FILE *fp,struct mbuf **bpp)
- {
- int16 n, address = 0;
- char buf[16];
-
- if(bpp == NULLBUFP || *bpp == NULLBUF)
- return;
-
- while((n = pullup(bpp,buf,sizeof(buf))) != 0){
- fmtline(fp,address,buf,n);
- address += n;
- }
- }
-
- /* Dump an mbuf in ascii */
- static void near
- ascii_dump(FILE *fp,struct mbuf **bpp)
- {
- char *cp, buf[80];
- unsigned char c, cc, len;
-
- if(bpp == NULLBUFP || *bpp == NULLBUF)
- return;
-
- while((len = pullup(bpp,buf,sizeof(buf))) != 0) {
- cp = buf;
- while(len-- != 0) {
- cc = c = uchar(*cp);
- *cp++ = (c == 13) ? '\n' : (c < 0x20) ? '∙' : c;
- }
- *cp++ = '\0';
- trprintf(fp,"%s",buf);
- }
- if(cc != 13)
- trprintf(fp,"\n");
- }
-
- static void near
- d_trace(struct iface *ifp)
- {
- tprintf("%s:",ifp->name);
-
- if(ifp->port){
- tputs(" Trace on master iface only");
- } else {
- if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT | IF_TRACE_RAW)){
- if(ifp->trace & IF_TRACE_IN)
- tputs(" input");
- if(ifp->trace & IF_TRACE_OUT)
- tputs(" output");
- if(ifp->trace & IF_TRACE_NOBC)
- tputs(" - no broadcasts");
- if(ifp->trace & IF_TRACE_HEX)
- tputs(" (Hex/ASCII dump)");
- else if(ifp->trace & IF_TRACE_ASCII)
- tputs(" (ASCII dump)");
- else
- tputs(" (headers only)");
- if(ifp->trace & IF_TRACE_RAW)
- tputs(" Raw output");
- if(ifp->trfile != NULLCHAR)
- tprintf(" trace file: %s",ifp->trfile);
- } else {
- tputs(" tracing off");
- }
- }
- tputs("\n");
- }
-
- /* Modify or displace interface trace flags */
- int
- dotrace(int argc,char *argv[],void *p)
- {
- struct iface *ifp;
-
- if(argc < 2){
- for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- d_trace(ifp);
- } else {
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badif,argv[1]);
- return 1;
- }
- if(argc == 2) {
- d_trace(ifp);
- return 0;
- }
- if(argc >= 3)
- ifp->trace = htoi(argv[2]);
-
- /* Always default to stdout unless trace file is given */
- if(ifp->trfp != NULLFILE && ifp->trfp != stdout)
- fclose(ifp->trfp);
- ifp->trfp = stdout;
- if(ifp->trfile != NULLCHAR)
- xfree(ifp->trfile);
- ifp->trfile = NULLCHAR;
-
- if(argc >= 4){
- if((ifp->trfp = open_file(argv[3],APPEND_TEXT,0,1)) == NULLFILE){
- ifp->trfp = stdout;
- } else {
- ifp->trfile = strxdup(argv[3]);
- }
- }
- }
- return 0;
- }
-
- /* shut down all trace files */
- void
- shuttrace(void)
- {
- struct iface *ifp;
-
- for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next){
- if(ifp->trfp != NULLFILE && ifp->trfp != stdout)
- fclose(ifp->trfp);
- if(ifp->trfile != NULLCHAR)
- xfree(ifp->trfile);
- ifp->trfile = NULLCHAR;
- ifp->trfp = NULLFILE;
- }
- }
-
- int
- trprintf(FILE *fp,char *fmt,...)
- {
- va_list ap;
- char tmp[LINELEN]; /* DB3FL */
- int len = 0;
-
- va_start(ap,fmt);
- vsprintf(tmp,fmt,ap);
- va_end(ap);
-
- if(fp != 0 && fp != stdout)
- fputs(tmp,fp);
- if (Current == Trace) {
- char *cp = tmp;
- for (;*cp;cp++) {
- switch (*cp) {
- case '\r':
- continue;
- case '\n':
- putch('\r');
- putch('\n');
- len++;
- continue;
- }
- putch(*cp);
- len++;
- }
- }
- return len;
- }